/*
 * @Author: taoyuqing
 * @Date: 2023-01-10 02:35:27
 * @Description: 
 */
import 'dart:convert';
import 'package:animated_digit/animated_digit.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_animation_progress_bar/flutter_animation_progress_bar.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:spree/pages/games/allGame/crash/SnowBean.dart';
import 'package:spree/pages/games/allGame/crash/SnowCustomPainter.dart';
import 'package:spree/pages/games/game_manual.dart';
import 'package:spree/pages/games/game_progress.dart';
import 'package:spree/pages/games/games_auto.dart';
import 'package:spree/pages/games/games_num_button.dart';
import 'package:spree/pages/games/games_table.dart';
import 'package:spree/utils/account.dart';
import 'package:spree/utils/api.dart';
import 'package:spree/utils/utils.dart';
import 'package:spree/utils/videoUtil.dart';
import 'package:spree/widgets/common_container.dart';
import 'dart:math' as math;
import 'dart:math';
import 'package:spree/widgets/vip_content_box.dart';
import 'package:spree/widgets/vip_rectangle_box.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;
import '../../../../provider/model/user_model.dart';
import '../../../../utils/precision_limit_formatter.dart';
import '../../game_title_bar.dart';
import 'DataModel.dart';
import 'DrawLine.dart';

class CrashPage extends StatefulWidget {
  CrashPage({Key? key}) : super(key: key);

  @override
  State<CrashPage> createState() => _CrashPageState();
}

class _CrashPageState extends State<CrashPage> with TickerProviderStateMixin {
  late TabController _tabController;
  late TabController _tabController2;
  late AnimatedDigitController _accountAmountController;
  List _tabs = ["Manual", "Auto"];
  List _tabs2 = ["My Bets", "History", "Player List"];
  int _fIndex = 0;
  int _fIndex2 = 0;
  final IO.Socket _socket = IO.io(
      'http://47.95.0.143:9005',
      IO.OptionBuilder()
          .setPath('/game/socket.io')
          .setTransports(['websocket'])
          .disableAutoConnect()
          .build());
  List<SnowBean> _list = [];
  Random _random = new Random(DateTime.now().microsecondsSinceEpoch);
  late AnimationController snowAnimationController = new AnimationController(
      vsync: this, duration: Duration(milliseconds: 10000));
  late AnimationController animationController =
      AnimationController(vsync: this, duration: Duration(milliseconds: 1000));
  late AnimationController userShowAnimationController =
      new AnimationController(
          vsync: this, duration: Duration(milliseconds: 500));
  late Animation<double> userAnimation =
      Tween(begin: 1.0, end: 0.0).animate(userShowAnimationController);
  late Animation animation =
      Tween(begin: 0.0, end: 1.0).animate(animationController);

  late AnimationController progressAnimationController =
      AnimationController(vsync: this, duration: Duration(milliseconds: 10000));
  late Animation progressAnimation =
      Tween(begin: 0.0, end: 1.0).animate(progressAnimationController);

  //crash飞机
  late DataModel dataModel = DataModel();
  var start = Offset(40, 220);
  var controlPoint = Offset.zero;
  var end = Offset.zero;
  // var start = Offset(40, 220);
  // var controlPoint = Offset(360, 220);
  // var end = Offset(360, 90);
  late TextEditingController _textEditingController;
  late TextEditingController _lootIn;
  int _minButtonSelect = 0;
  //显示progrss相关的
  double progress = 10;
  String progressStr = "";
  String crashMutiplier = "";
  //BET按钮的状态相关
  String betStatus = "BET";
  String cancel = "CANCEL";
  String betNextRound = "BET NEXT ROUND";
  String betStr = "BET";
  String cashOut = "CASHOUT";
  String betPlaced = "BET IS PLACED";
  Color color = Color(0xFF7A50F0);
  Color otherColor = Color(0xFFFF506F);
  Color betPlaceColor = Color(0xffFF8096);
  Color originColor = Color(0xFF7A50F0);

  //是否已经点击BET,如果点击了BET之后，不能再做操作了
  bool hasClickBet = false;
  bool hasSettle = false;
  //下一局是否下单
  bool nextRoundOrder = false;
  //是否是新的对局
  List _smallButtons = [];
  // 爆照
  bool _crashBoom = false;
  //显示相关的
  bool placeBetVisible = false;
  bool progressVisible = false;
  bool progressTextVisible = false;
  bool historyVisble = false;
  bool hasPlayVideo = false;
  bool betSuccess = true;
  // 表头
  List<String> _myBetHeader = [
    'Bet ID',
    // 'Game ID',
    'Time',
    'Bet',
    'Cash Out',
    'Profit'
  ];
  List<String> _playerHeader = ['Player', 'Cash Out', 'Bets'];
  List<String> _historyHeader = ['Round ID', 'Time', 'Result'];
  // 数据
  List<Map> _myBetData = [];
  List<Map> _playerData = [];

  List<Map> _history = [];

  //历史记录
  List rollHistoryNumber = [];
  // 是否显示用户
  bool _showUser = false;
  String? userName = "";
  double _money = 0;
  // 是否显示输赢结果
  bool _showResult = false;
  // 输赢
  bool _isWin = false;
  String cashOutMoney = "";

  final GlobalKey crashBackgroundContainer = GlobalKey();

  final GlobalKey crashEntity = GlobalKey();

  final GlobalKey fireEntity = GlobalKey();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _tabController = TabController(length: _tabs.length, vsync: this);
    _tabController2 = TabController(length: _tabs2.length, vsync: this);
    _textEditingController = TextEditingController(text: '');
    _lootIn = TextEditingController(text: '1.01');
    //执行刷新监听
    snowAnimationController.addListener(_snowAnimationControllerListener);
    //开启气泡的运动
    snowAnimationController.repeat();
    SchedulerBinding.instance.addPostFrameCallback((_) {
      double width = Utils().getScreenWidth(context);
      controlPoint = Offset(width * 36 / 43, 220);
      end = Offset(width * 36 / 43, 90);
      // double? crashContainerWidth =
      //     crashBackgroundContainer.currentContext?.size?.width;
      // double? crashContainerHeight =
      //     crashBackgroundContainer.currentContext?.size?.height;

      // double? crashEntityWidth = crashEntity.currentContext?.size?.width;

      // double? crashEntityHeight = crashEntity.currentContext?.size?.height;

      // double? startX = crashEntityWidth! * 1 / 2;
      // double? startY = crashContainerHeight! - 1 / 2 * crashEntityHeight!;
      // double crashMoveX = crashContainerWidth! - crashEntityWidth! / 2;
      // double crashMoveY = crashEntityWidth / 2;
      // print("$crashMoveX====$crashMoveY");
      // double width = Utils().getScreenWidth(context);
      // start = Offset(0, 0);
      // controlPoint = Offset(crashMoveX, 0);
      // end = Offset(crashMoveX, -crashMoveY);
    });

    progressAnimation.addListener(_progressAnimationListener);
    progressAnimationController
        .addStatusListener(_progressAnimationControllerStatusListener);
    animation.addListener(_animationListener);
    animationController.addStatusListener(_animationControllerStatusListener);
    userShowAnimationController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _showUser = false;
        userShowAnimationController.reset();
      }
    });
    crashMutiplier = "1.00";
    wsConnect(context);
    String accountAmount = context.read<UserModel>().accountAmount;

    if (accountAmount != '') {
      _accountAmountController =
          AnimatedDigitController(double.parse(accountAmount));
    } else {
      _accountAmountController = AnimatedDigitController(0.00);
    }
    setState(() {});
    getMyBetsAndAccount();
  }

// 初始化ws
  wsConnect(BuildContext context) async {
    try {
      final prefs = await SharedPreferences.getInstance();
      String? userId = context.read<UserModel>().userId;
      _socket.connect();
      _socket.onConnect((data) async {
        Map pre = {'gameType': 'CRASH'};
        sendMsg('game_enter', pre);
        _onMessage(userId);
      });
      _socket.onDisconnect((data) {
        print('断开=====');
      });

      // _onMessage(context);
    } catch (e) {
      print(e);
    }
  }

  // 监听消息
  _onMessage(String? userId) {
    try {
      _socket.on('game_pre', (data) {});
      _socket.on('game_start_time', ((data) async {
        // int startTime = int.parse(data.toString());
        // int current = DateTime.now().millisecondsSinceEpoch;
        // int current

        Map result = jsonDecode(data);
        int startTime = result['gameStartTime'];
        int current = result['current'];
        int delay = startTime - current;
        //如果延迟时间小于0说明要立即执行动画
        if (delay < 0) {
          animationController.duration = Duration(milliseconds: 500);
          hasPlayVideo = true;
          betStatus = betNextRound;
          color = otherColor;
          if (mounted) {
            _rocketStart();
          }
          return;
        } else {
          //间隔时间太小了，不播放音乐
          if (delay <= 4000) {
            hasPlayVideo = true;
          }
          if (mounted) {
            progressRun(delay);
          }
        }
        // print("游戏延迟时间$delay");
      }));
      _socket.on('crash_info', (data) {
        Map result = jsonDecode(data);
        String crashState = result['crashState'];
        double mutiplier = 1.00;
        //如果当前是下一局要下单

        if (mounted) {
          if (crashState == "FLY") {
            mutiplier = result['mutiplier'];
            double autoStopMutiplier = 0.0;
            if (_lootIn.text != '') {
              autoStopMutiplier = double.parse(_lootIn.text);
            }
            if (hasClickBet &&
                !hasSettle &&
                mutiplier >= autoStopMutiplier &&
                betSuccess) {
              autoCashOut();
            }
            setState(() {
              crashMutiplier = mutiplier.toStringAsFixed(2);
              if (hasClickBet) {
                cashOutMoney =
                    (double.parse(_textEditingController.text) * mutiplier)
                        .toStringAsFixed(2);
              }
            });
          } else {
            //此时游戏结束，需要重新倒计时
            setState(() {
              crashMutiplier = "1.00";
              VideoUtil.playVideoByUrl("sounds/crash/crash_lose.mp3");
              if (hasClickBet && !hasSettle) {
                handleMoneyMin();
              }
              _crashBoom = true;
            });
            Future.delayed(const Duration(milliseconds: 1500), gameReset);
          }
        }
      });
      _socket.on("game_start", ((data) {
        Map result = jsonDecode(data);
        userName = result['userName'];
        if (mounted) {
          showUser();
        }
        getMyBets();
      }));
      _socket.on("game_bet", ((data) {
        Map result = jsonDecode(data);
        bool success = result['success'];
        if (!success) {
          setState(() {
            betSuccess = false;
          });

          String errorMsg = result['errorMsg'];
          _showChargeAlert(errorMsg);
          // EasyLoading.showError(errorMsg);
        } else {
          setState(() {
            betSuccess = true;
            changeBetStatusToBetPlaced();
          });
        }
      }));
      _socket.on("game_history", ((data) {
        //游戏上方的历史记录
        List result = jsonDecode(data);
        rollHistoryNumber = [];
        _smallButtons = [];
        if (mounted) {
          setState(() {
            if (result.length > 0) {
              for (int i = 0; i < result.length; i++) {
                rollHistoryNumber.add(result[i]['mutiplier']);
              }
              int size = rollHistoryNumber.length;

              if (size > 0) {
                if (size >= 6) {
                  for (int i = 5; i >= 0; i--) {
                    _smallButtons.add(rollHistoryNumber[i]);
                  }
                } else {
                  for (int i = size - 1; i >= 0; i--) {
                    _smallButtons.add(rollHistoryNumber[i]);
                  }
                }
              }
            }
          });
        }

        _history = [];
        // 游戏下方的记录
        // {'roundID': '112324001', 'time': '2023-01-02', 'result': '1.2x'}
        if (result.length > 0) {
          for (int i = 0; i < result.length; i++) {
            _history.add({
              'roundID': result[i]['roundId'],
              'time': result[i]['time'],
              'result': result[i]['mutiplier']
            });
          }
        }
      }));
      _socket.on("game_real_time_crash", ((data) {
        // {'player': 'User2122322222222', 'cashOut': '1.2x', 'bets': '50'}
        List result = jsonDecode(data);
        _playerData = [];
        if (result.length > 0) {
          for (int i = 0; i < result.length; i++) {
            _playerData.add({
              'player': result[i]['userName'],
              'cashOut': result[i]['mutiplier'].toString() + 'x',
              'bets': result[i]['betAmount'],
              'win': result[i]['win']
            });
          }
        }
      }));
    } catch (e) {
      print(e);
    }
  }

  // 发送消息
  sendMsg(msg, prama) {
    print(prama);
    try {
      _socket.emit(msg, prama);
    } catch (e) {}
  }

  // 断开连接
  disConnect() {
    try {
      _socket.onDisconnect((data) {});
    } catch (e) {}
  }

  @override
  void didChangeDependencies() {
    // TODO: implement didChangeDependencies
    super.didChangeDependencies();
  }

  @override
  void dispose() {
    progressAnimationController.dispose();
    animationController.dispose();
    _tabController.dispose();
    _tabController2.dispose();
    snowAnimationController.dispose();
    if (_socket != null) {
      _socket.clearListeners();
      _socket.disconnect();
    }
    super.dispose();
  }

  void initData() {
    _list = [];
    for (int i = 0; i < 10; i++) {
      SnowBean bean = new SnowBean();
      //获取随机透明度白色
      bean.color = getRandomWhiteColor();
      //设置位置 先来个默认的 绘制的时候再修改
      double x = _random.nextDouble() * MediaQuery.of(context).size.width * 0.9;
      double y = _random.nextDouble() * MediaQuery.of(context).size.height;
      double z = _random.nextDouble() + 0.5;
      bean.speed = _random.nextDouble() + 0.9 / z;
      bean.postion = Offset(x, y);
      bean.origin = Offset(x, 0);
      //设置半径
      bean.radius = 1.0 / z;
      _list.add(bean);
    }
  }

  _progressAnimationListener() {
    setState(() {
      progress = (1 - progressAnimation.value) * 10;
      if (progress <= 4 && !hasPlayVideo) {
        VideoUtil.playVideoByUrl("sounds/time_delay.mp3");
        hasPlayVideo = true;
      }
      progressStr = progress.toStringAsFixed(2);
    });
  }

  _snowAnimationControllerListener() {
    setState(() {});
  }

  _animationListener() {
    setState(() {
      updateOffset();
    });
  }

  _animationControllerStatusListener(status) {
    if (animationController.isCompleted) {
      setState(() {
        //如果当前已经下单
      });
    }
  }

  _progressAnimationControllerStatusListener(status) {
    if (progressAnimationController.isCompleted) {
      _rocketStart();
      setState(() {
        progressVisible = false;
        progressTextVisible = false;
        historyVisble = false;
        placeBetVisible = false;
        hasPlayVideo = false;
        if (betStatus == betPlaced) {
          betStatus = cashOut;
          color = otherColor;
          return;
        } else {
          betStatus = betNextRound;
          color = otherColor;
          return;
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              SvgPicture.asset('images/BETSPREELOGO.svg'),
              _circleMoney(),
            ],
          ),
        ),
        body: Consumer<UserModel>(builder: (context, value, child) {
          return CommonContainer(
            child: ListView(
              children: [
                GameTitleBar(
                  gameName: 'Crash',
                  ontap: (type) {
                    if (type == 'info') {
                      Navigator.pushNamed(context, 'CrashRules');
                    }
                  },
                ),
                Stack(
                  children: [
                    Container(
                      key: crashBackgroundContainer,
                      width: Utils().getScreenWidth(context),
                      height: 240,
                      decoration: BoxDecoration(
                          color: Utils().createMaterialColor(),
                          image: const DecorationImage(
                              image: AssetImage(
                                'images/games/crash/background.png',
                              ),
                              fit: BoxFit.fill)),
                      child: CustomPaint(
                        size: MediaQuery.of(context).size,
                        painter:
                            SnowCustomMyPainter(list: _list, random: _random),
                      ),
                    ),
                    Offstage(
                      offstage: _crashBoom,
                      child: CustomPaint(
                        painter: DrawLine(
                            start: start,
                            controlPoint: controlPoint,
                            end: end,
                            t: animation.value),
                      ),
                    ),
                    Positioned(
                      left: 10,
                      bottom: 10,
                      child: Transform(
                        origin: Offset(35, 40),
                        transform: Matrix4.identity()
                          ..translate(dataModel.left, dataModel.top)
                          ..rotateZ(dataModel.rotate),
                        // alignment: Alignment.bottomLeft,
                        child: Stack(
                          children: [
                            // crashBoom.png
                            !_crashBoom
                                ? Positioned(
                                    child: Image.asset(
                                    key: crashEntity,
                                    'images/games/crash/crash.png',
                                    width: 100,
                                    height: 60,
                                  ))
                                : Positioned(
                                    child: Image.asset(
                                    'images/games/crash/bomb.gif',
                                    height: 60,
                                    width: 100,
                                  )),
                            !_crashBoom
                                ? Positioned(
                                    left: -55,
                                    bottom: -15,
                                    height: 70,
                                    child: Transform.rotate(
                                      //旋转90度
                                      angle: -math.pi / 2,
                                      child: Image.asset(
                                          key: fireEntity,
                                          'images/games/crash/fire.gif'),
                                    ),
                                  )
                                : Container(),
                          ],
                        ),
                      ),
                    ),
                    Visibility(
                      visible: historyVisble,
                      child: Container(
                        margin: EdgeInsets.only(top: 20, left: 40, right: 40),
                        child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceAround,
                            children: _createNumberButton()),
                      ),
                    ),
                    Container(
                        child: Container(
                      margin: EdgeInsets.only(top: 60),
                      width: Utils().getScreenWidth(context),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          Text(
                            '$crashMutiplier' + 'x',
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 40,
                                fontWeight: FontWeight.w800),
                          ),
                          Visibility(
                            visible: placeBetVisible,
                            child: const Text(
                              'Place your Bet',
                              style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 12,
                                  fontWeight: FontWeight.w800),
                            ),
                          ),
                          Visibility(
                            visible: progressVisible,
                            child: ConstrainedBox(
                              constraints: BoxConstraints(maxWidth: 200),
                              child: SliderTheme(
                                data: SliderTheme.of(context)
                                    .copyWith(thumbShape: ProgressBar()),
                                child: Slider(
                                  value: progress,
                                  max: 10,
                                  min: 0,
                                  activeColor: Color(0xFF5484FF),
                                  inactiveColor: Color(0xFFFF3F61),
                                  onChanged: (value) {},
                                ),
                              ),
                            ),
                          ),
                          Visibility(
                            visible: progressTextVisible,
                            child: Text(
                              '$progressStr',
                              style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 12,
                                  fontWeight: FontWeight.w800),
                            ),
                          )
                        ],
                      ),
                    )),
                    Visibility(
                        visible: _showUser,
                        child: TweenAnimationBuilder(
                          builder: (context, value, child) {
                            return Container(
                              child: Positioned(
                                right: 10 * (2 - userAnimation.value),
                                top: 50 * (2 - userAnimation.value),
                                child: FadeTransition(
                                  opacity: userAnimation,
                                  child: Container(
                                    alignment: Alignment.topRight,
                                    width: 100,
                                    height: 200,
                                    child: Stack(
                                      children: [
                                        Positioned(
                                          top: 0,
                                          right: 0,
                                          child: Text(
                                            '$userName',
                                            style:
                                                TextStyle(color: Colors.white),
                                          ),
                                        )
                                      ],
                                    ),
                                  ),
                                ),
                              ),
                            );
                          },
                          tween: Tween(begin: 1.0, end: 0.0),
                          duration: Duration(milliseconds: 2000),
                        )),
                    Visibility(
                      child: Container(
                        margin: EdgeInsets.only(top: 80),
                        width: Utils().getScreenWidth(context),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [_isWinWidget(_isWin, '4.5')],
                        ),
                      ),
                      visible: _showResult,
                    ),
                  ],
                ),
                Container(
                  margin: EdgeInsets.only(top: 20),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Expanded(
                        child: Container(
                          height: 80,
                          alignment: Alignment.center,
                          margin: EdgeInsets.only(right: 10),
                          padding: EdgeInsets.only(
                              left: 10, right: 10, top: 4, bottom: 4),
                          decoration: BoxDecoration(
                            border: _loutLine(),
                            borderRadius:
                                const BorderRadius.all(Radius.circular(10.0)),
                          ),
                          child: Row(
                            children: [
                              _minButton(
                                  onTap: () {
                                    if (nextRoundOrder) {
                                      return;
                                    }
                                    if (hasClickBet) {
                                      return;
                                    }
                                    try {
                                      double t = double.parse(_lootIn.text);
                                      if (t >= 2) {
                                        _lootIn.text =
                                            (t - 1).toStringAsFixed(2);
                                      }

                                      if (t < 1) {
                                        return;
                                      }
                                    } catch (e) {
                                      _lootIn.text = '1.00';
                                    }
                                  },
                                  child: Text(
                                    '-',
                                    style: TextStyle(color: _whiteColor()),
                                  )),
                              Expanded(
                                child: Column(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    Container(
                                      width: 80,
                                      child: TextField(
                                        toolbarOptions:
                                            ToolbarOptions(paste: false),
                                        controller: _lootIn,
                                        textAlign: TextAlign.center,
                                        style: TextStyle(color: Colors.white),
                                        keyboardType: TextInputType.number,
                                        inputFormatters: [
                                          // FilteringTextInputFormatter.allow(
                                          //     RegExp("[0-9]"))
                                          PrecisionLimitFormatter(2),
                                        ],
                                        cursorColor: Colors.white,
                                        decoration: InputDecoration(
                                          border: InputBorder.none,
                                        ),
                                      ),
                                    ),
                                    Text(
                                      'Loot In',
                                      style: TextStyle(
                                          color: _whiteColor(),
                                          fontWeight: FontWeight.w800),
                                    )
                                  ],
                                ),
                                flex: 1,
                              ),
                              _minButton(
                                  onTap: () {
                                    if (nextRoundOrder) {
                                      return;
                                    }
                                    if (hasClickBet) {
                                      return;
                                    }
                                    try {
                                      double t = double.parse(_lootIn.text);
                                      _lootIn.text = (t + 1).toStringAsFixed(2);
                                    } catch (e) {
                                      _lootIn.text = '1.00';
                                    }
                                  },
                                  child: Text(
                                    '+',
                                    style: TextStyle(color: _whiteColor()),
                                  )),
                            ],
                          ),
                        ),
                        flex: 4,
                      ),
                      Expanded(
                        child: Container(
                          height: 80,
                          alignment: Alignment.center,
                          padding: EdgeInsets.only(
                              left: 10, right: 10, top: 4, bottom: 4),
                          decoration: BoxDecoration(
                            border: _loutLine(),
                            borderRadius:
                                const BorderRadius.all(Radius.circular(10.0)),
                          ),
                          child: Row(
                            children: [
                              Column(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceAround,
                                children: [
                                  _minButton(
                                      isSelect: _minButtonSelect == 1,
                                      onTap: () {
                                        if (nextRoundOrder) {
                                          return;
                                        }
                                        if (hasClickBet) {
                                          return;
                                        }
                                        setState(() {
                                          _textEditingController.text = '0';
                                          setState(() {
                                            _minButtonSelect = 1;
                                          });
                                        });
                                      },
                                      child: Text(
                                        'Min',
                                        style: TextStyle(color: _whiteColor()),
                                      )),
                                  _minButton(
                                      isSelect: _minButtonSelect == 2,
                                      onTap: () {
                                        if (nextRoundOrder) {
                                          return;
                                        }
                                        if (hasClickBet) {
                                          return;
                                        }
                                        setState(() {
                                          _textEditingController.text = '1000';

                                          _minButtonSelect = 2;
                                        });
                                      },
                                      child: Text(
                                        'Max',
                                        style: TextStyle(color: _whiteColor()),
                                      ))
                                ],
                              ),
                              Expanded(
                                child: Column(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    Text(
                                      'R\$',
                                      style: TextStyle(
                                          color: _whiteColor(),
                                          fontWeight: FontWeight.w800),
                                    ),
                                    TextField(
                                      toolbarOptions:
                                          ToolbarOptions(paste: true),
                                      controller: _textEditingController,
                                      textAlign: TextAlign.center,
                                      style: TextStyle(color: Colors.white),
                                      keyboardType: TextInputType.number,
                                      inputFormatters: [
                                        // FilteringTextInputFormatter.allow(
                                        //     RegExp("[0-9]"))
                                        PrecisionLimitFormatter(2)
                                      ],
                                      cursorColor: Colors.white,
                                      decoration: InputDecoration(
                                        border: InputBorder.none,
                                      ),
                                    )
                                  ],
                                ),
                                flex: 1,
                              ),
                              Column(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceBetween,
                                children: [
                                  _minButton(
                                      isSelect: _minButtonSelect == 3,
                                      onTap: () {
                                        if (nextRoundOrder) {
                                          return;
                                        }
                                        if (hasClickBet) {
                                          return;
                                        }
                                        setState(() {
                                          _minButtonSelect = 3;
                                        });
                                        try {
                                          _textEditingController.text =
                                              '${double.parse(_textEditingController.text) ~/ 2}';
                                        } catch (e) {}
                                        ;
                                      },
                                      child: Text(
                                        '1/2',
                                        style: TextStyle(color: _whiteColor()),
                                      )),
                                  _minButton(
                                      isSelect: _minButtonSelect == 4,
                                      onTap: () {
                                        if (nextRoundOrder) {
                                          return;
                                        }
                                        if (hasClickBet) {
                                          return;
                                        }
                                        setState(() {
                                          _minButtonSelect = 4;

                                          _textEditingController.text =
                                              '${double.parse(_textEditingController.text) * 2}';
                                        });
                                      },
                                      child: Text(
                                        '2x',
                                        style: TextStyle(color: _whiteColor()),
                                      ))
                                ],
                              ),
                            ],
                          ),
                        ),
                        flex: 6,
                      ),
                    ],
                  ),
                ),
                Container(
                  margin: EdgeInsets.only(top: 20),
                  height: 50,
                  child: ElevatedButton(
                      onPressed: betStatus == betPlaced
                          ? null
                          : () {
                              //判断登录
                              if (value.userId == '') {
                                Navigator.pushNamed(context, 'LoginPage')
                                    .then((user) {
                                  wsConnect(context);
                                  Map pre = {'gameType': 'CRASH'};
                                  sendMsg('game_enter', pre);
                                  getMyBetsAndAccount();
                                });
                                return;
                              }
                              if (_textEditingController.text == "" ||
                                  _textEditingController.text == "0") {
                                EasyLoading.showToast("please typed in amount");
                                return;
                              }
                              changeStatus();
                              //这个时候是可以押注的
                            },
                      style: ButtonStyle(
                        backgroundColor: MaterialStateProperty.all(color),
                      ),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text(
                            '$betStatus',
                            style: TextStyle(
                                color: Utils().whiteColor(), fontSize: 20),
                          ),
                          betStatus == cashOut
                              ? Visibility(
                                  visible: true,
                                  child: Text(
                                    '$cashOutMoney',
                                    style: TextStyle(
                                        color: Utils().whiteColor(),
                                        fontSize: 12),
                                  ))
                              : Container()
                        ],
                      )),
                ),
                TabBar(
                  controller: _tabController,
                  tabs: _tabs.map((e) => Tab(text: e)).toList(),
                  onTap: (i) {
                    setState(() {
                      _fIndex = i;
                    });
                  },
                ),
                _fIndex == 1 ? GamesAuto() : Container(),
                TabBar(
                  indicator: const UnderlineTabIndicator(
                      borderSide: BorderSide(width: 2.0, color: Colors.red)),
                  controller: _tabController2,
                  tabs: _tabs2
                      .map((e) => Tab(
                            text: e,
                          ))
                      .toList(),
                  onTap: (i) {
                    setState(() {
                      _fIndex2 = i;
                    });
                  },
                ),
                VipRectangleBox(
                  color: Color(0xFF291F62),
                  child: SingleChildScrollView(
                    scrollDirection: Axis.horizontal,
                    child: _tableList(_fIndex2),
                  ),
                ),
              ],
            ),
          );
        }));
  }

  Widget _tableList(index) {
    if (index == 1) {
      return DataTable(
        columns: _historyHeader.map((e) {
          return DataColumn(
            label: Text(
              '$e',
              style: TextStyle(color: Colors.white38),
            ),
          );
        }).toList(),
        rows: _createTableRow(_history, ['roundID', 'time', 'result']),
      );
    }
    if (index == 2) {
      return DataTable(
        columns: _playerHeader.map((e) {
          return DataColumn(
            label: Text(
              '$e',
              style: TextStyle(color: Colors.white38),
            ),
          );
        }).toList(),
        rows: _createTableRow(_playerData, ['player', 'cashOut', 'bets']),
      );
    }
    return DataTable(
      columns: _myBetHeader.map((e) {
        return DataColumn(
          label: Text(
            '$e',
            style: TextStyle(color: Colors.white38),
          ),
        );
      }).toList(),
      rows: _createTableRow(
          _myBetData, ['betId', 'time', 'bet', 'cashOut', 'profit']),
    );
  }

  List<DataRow> _createTableRow(List<Map> data, List<String> keys) {
    return data.map((e) => DataRow(cells: _createTableCell(e, keys))).toList();
  }

  List<DataCell> _createTableCell(Map data, List<String> keys) {
    return keys.map((e) {
      if (['bet', 'profit', 'bets'].contains(e)) {
        return DataCell(
          Row(
            children: [
              Text(
                'R\$ ',
                style: TextStyle(color: Color(0xFFFFED4A)),
              ),
              Text(
                '${data[e]}',
                style: TextStyle(color: Colors.white),
              ),
            ],
          ),
        );
      }
      if (['cashOut', 'result'].contains(e)) {
        if (e == 'cashOut') {
          Color color = Colors.green;
          if (data['profit'] == '0.00' || data['win'] == false) {
            color = Colors.red;
          }
          return DataCell(
            Container(
              width: 50,
              height: 20,
              decoration: BoxDecoration(
                color: color,
                borderRadius: BorderRadius.all(Radius.circular(3.0)),
              ),
              alignment: Alignment.center,
              child: Text(
                '${data[e]}',
                style: TextStyle(color: Colors.white),
              ),
            ),
          );
        } else {
          Color color = getColorByNum(data['result']);
          return DataCell(
            Container(
              width: 50,
              height: 20,
              decoration: BoxDecoration(
                color: color,
                borderRadius: BorderRadius.all(Radius.circular(3.0)),
              ),
              alignment: Alignment.center,
              child: Text(
                '${data[e]}' + 'x',
                style: TextStyle(color: Colors.white),
              ),
            ),
          );
        }
      }
      return DataCell(Text(
        '${data[e]}',
        style: TextStyle(color: Colors.white60),
      ));
    }).toList();
  }

  // 边框的container
  Border _loutLine() {
    return Border.all(width: 1, color: Color.fromRGBO(255, 255, 255, 0.5));
  }

  Widget _minButton(
      {Widget? child, EdgeInsets? margin, Function? onTap, bool? isSelect}) {
    return GestureDetector(
      onTap: () {
        if (onTap != null) {
          onTap();
        }
      },
      child: Container(
        margin: margin,
        decoration: BoxDecoration(
          color: isSelect == true ? Color(0xFF7A50F0) : Color(0xFF413497),
          borderRadius: const BorderRadius.all(Radius.circular(4.0)),
        ),
        padding: EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
        child: child,
      ),
    );
  }

  _showChargeAlert(String msg) {
    showDialog(
        barrierDismissible: false,
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text("Tips"),
            content: Text("$msg"),
            actions: <Widget>[
              TextButton(
                child: Text("Cancel"),
                onPressed: () => Navigator.of(context).pop(),
              ),
              TextButton(
                child: Text("Deposit"),
                onPressed: () {
                  // 跳转到充值页面
                  Navigator.pushNamed(context, 'DepositPage');
                  // Navigator.of(context).pop(true); //关闭对话框
                },
              ),
            ],
          );
        });
  }

  // 白色
  Color _whiteColor() {
    return Color(0xFFFFFFFF);
  }

  Offset updateOffset() {
    var t = animation.value;
    Offset currentOffset = Offset(dataModel.left, dataModel.top);
    dataModel.left = ((1 - t) * (1 - t) * start.dx +
            2 * t * (1 - t) * controlPoint.dx +
            t * t * end.dx)
        .toDouble();
    dataModel.left = dataModel.left - 40;

    dataModel.top = ((1 - t) * (1 - t) * start.dy +
            2 * t * (1 - t) * controlPoint.dy +
            t * t * end.dy)
        .toDouble();
    dataModel.top = dataModel.top - 220;
    double rorate = -t * 90 / 180 * pi;
    dataModel.rotate = rorate;

    setState(() {});
    return currentOffset;
  }

  _rocketStart() {
    animationController.forward();
    initData();
  }

  showUser() {
    setState(() {
      _showUser = true;
      userShowAnimationController.forward();
    });
  }

  progressRun(int delay) {
    if (nextRoundOrder) {
      nextRoundOrder = false;
      order();
      hasClickBet = true;
    }
    historyVisble = true;
    progressVisible = true;
    progressTextVisible = true;
    progressAnimationController.reset();
    progressAnimationController.duration = Duration(milliseconds: delay);
    progressAnimationController.forward();
  }

  gameReset() {
    _crashBoom = false;
    _list = [];
    dataModel.left = 0;
    dataModel.top = 0;
    dataModel.rotate = 0;
    animationController.reset();
    animationController.duration = Duration(milliseconds: 1000);
    progressAnimationController.reset();
    betStatus = betStr;
    color = originColor;
    hasClickBet = false;
    _showUser = false;
    hasSettle = false;
    userShowAnimationController.reset();
    setState(() {
      progressVisible = true;
      progressTextVisible = true;
      historyVisble = true;
      placeBetVisible = true;
      hasPlayVideo = false;
    });
  }

  changeStatus() {
    setState(() {
      if (betStatus == betStr) {
        VideoUtil.playVideoByUrl("sounds/crash/crash_button_click.mp3");
        order();
        hasClickBet = true;
        //下单成功
        return;
      }
      if (betStatus == betNextRound) {
        VideoUtil.playVideoByUrl("sounds/crash/crash_button_click.mp3");
        //自动下注
        changeBetStatusToBetCancel();
        return;
      }
      if (betStatus == cancel) {
        VideoUtil.playVideoByUrl("sounds/crash/crash_button_click.mp3");
        //取消自动下注
        changeBetStatusToBetNextRound();
        return;
      }
      //主动投
      if (betStatus == cashOut) {
        handleCashOut();
      }
    });
  }

  changeBetStatusToBetPlaced() {
    betStatus = betPlaced;
    color = betPlaceColor;
  }

  changeBetStatusToBetCancel() {
    betStatus = cancel;
    nextRoundOrder = true;
  }

  changeBetStatusToBetNextRound() {
    betStatus = betNextRound;
    nextRoundOrder = false;
  }

//自动结算的逻辑
  autoCashOut() {
    VideoUtil.playVideoByUrl("sounds/crash/crash_win.mp3");
    betStatus = betNextRound;
    hasClickBet = false;
    hasSettle = true;
    handleMoneyAdd();
  }

  handleMoneyAdd() {
    double autoStop = double.parse(_lootIn.text);
    double inputMoney = double.parse(_textEditingController.text);
    double winAmount = autoStop * inputMoney;
    if (betSuccess) {
      _accountAmountController.addValue(winAmount);
    }
  }

  handleMoneyMin() {
    double inputMoney = double.parse(_textEditingController.text);
    if (betSuccess) {
      _accountAmountController.addValue(-inputMoney);
    }
  }

  //手动结算
  handleCashOut() {
    print("逃离时的倍率是$crashMutiplier");
    VideoUtil.playVideoByUrl("sounds/crash/crash_win.mp3");
    betStatus = betNextRound;
    hasClickBet = false;
    cashWin();
    handleMoneyAdd();
    return;
  }

  //下单
  order() {
    String? userId = context.read<UserModel>().userId;
    Map order = {
      "userId": userId,
      "gameType": "CRASH",
      "amount": _textEditingController.text,
      "autoStop": _lootIn.text
    };
    sendMsg("game_bet", order);
  }

  cashWin() {
    String? userId = context.read<UserModel>().userId;
    Map settle = {
      "userId": userId,
      "gameType": "CRASH",
      "amount": _textEditingController.text,
      "autoStop": _lootIn.text
    };
    sendMsg("game_start", settle);
  }

  getMyBets() async {
    //当前时间倒推1个月
    var now = DateTime.now();
    DateTime newMonth = DateTime(now.year, now.month - 1, now.day);
    String endDate = DateFormat("yyyy-MM-dd").format(now);
    String startDate = DateFormat("yyyy-MM-dd").format(newMonth);
    _myBetData = [];
    Map param = {
      'gameType': 'CRASH',
      'startDate': startDate,
      'endDate': endDate,
      'limit': 20,
      'pageSize': 10
    };
    try {
      dynamic result = await Api.historyInfo(param);
      List tempData = result['data'];
      print(tempData);
      if (tempData.length > 0) {
        for (int i = 0; i < tempData.length; i++) {
          _myBetData.add({
            'betId': tempData[i]['recordNo'],
            'time': tempData[i]['playTime'],
            'bet': tempData[i]['betAmount'],
            'cashOut': tempData[i]['payOut'].toStringAsFixed(2) + 'x',
            'profit': tempData[i]['winAmount'].toStringAsFixed(2)
          });
        }
      }
    } catch (e) {
      print(e);
    }
  }

  Color getRandomWhiteColor() {
    //透明度 0 ~ 200  255是不透明
    Color color = Color.fromRGBO(255, 255, 204, 1);
    List colors = [
      Color.fromRGBO(255, 255, 204, 1),
      Color.fromRGBO(255, 255, 255, 1),
      Color.fromRGBO(255, 255, 153, 1)
    ];
    Random random = new Random();
    return colors[random.nextInt(colors.length)];
  }

  List<Widget> _createNumberButton() {
    return _smallButtons.map((e) {
      Color bgColor = Colors.red;
      double mutiplier = 1.0;
      if (e != null) {
        mutiplier = double.parse(e.toString());
      }
      if (e != null) {
        bgColor = getColorByNum(mutiplier);
      }

      return GameNumButton(
        number: '$mutiplier' + 'x',
        bgColor: bgColor,
      );
    }).toList();
  }

  Color getColorByNum(double mutiplier) {
    Color bgColor = Colors.red;
    if (mutiplier <= 1.2) {
      bgColor = Color(0xffe04461);
    }
    if (mutiplier > 1.2 && mutiplier <= 2) {
      bgColor = Color(0xff3ecc7f);
    }
    if (mutiplier > 2 && mutiplier <= 5) {
      bgColor = Color(0xff03bcca);
    }
    if (mutiplier > 5 && mutiplier <= 20) {
      bgColor = Color(0xff328fde);
    }
    if (mutiplier > 20) {
      bgColor = Color(0xffec8f40);
    }
    return bgColor;
  }

  Widget _isWinWidget(bool win, String num) {
    return win
        ? Container(
            width: 200,
            height: 100,
            alignment: Alignment.center,
            child: Column(
              children: [
                Text(
                  'You Won',
                  style: TextStyle(
                      color: Color(0xFF23FB1E),
                      fontSize: 30,
                      fontWeight: FontWeight.w700),
                ),
                Text(
                  '@${num}x',
                  style: TextStyle(
                      color: Color(0xFF23FB1E),
                      fontSize: 30,
                      fontWeight: FontWeight.w700),
                ),
              ],
            ),
            decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage('images/games/crash/winBg.png'),
                fit: BoxFit.cover, // 完全填充
              ),
            ),
          )
        : Column(
            children: [
              Text(
                'Bang',
                style: TextStyle(
                    color: Color(0xFFFF354D),
                    fontSize: 30,
                    fontWeight: FontWeight.w700),
              ),
              Text(
                '@${num}x',
                style: TextStyle(
                    color: Color(0xFFFF354D),
                    fontSize: 30,
                    fontWeight: FontWeight.w700),
              ),
            ],
          );
  }

  getMyBetsAndAccount() {
    String? userId = context.read<UserModel>().userId;
    if (userId != '') {
      getMyBets();
      Future.delayed(Duration(milliseconds: 200), (() {
        Account.refreshAccount(context);
      }));
    }
    String accountAmount = context.read<UserModel>().accountAmount;
    if (accountAmount != '') {
      _accountAmountController.value = double.parse(accountAmount);
    }
    setState(() {});
  }

  _circleMoney({double? width}) {
    return Row(
      children: [
        Container(
          width: width,
          margin: EdgeInsets.only(left: 12),
          padding: EdgeInsets.only(top: 4, bottom: 4, left: 8, right: 8),
          decoration: BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(20.0)),
              border: Border.all(color: Color(0xFF9C4EFF), width: 1)),
          child: Row(
            children: [
              Container(
                width: 24,
                height: 24,
                alignment: Alignment.center,
                decoration: BoxDecoration(
                    color: Color(0xFF9174FB),
                    borderRadius: BorderRadius.all(Radius.circular(12.0))),
                child: Text(
                  "R\$",
                  style: TextStyle(
                    fontSize: 10,
                    color: Colors.white,
                  ),
                ),
              ),
              Padding(
                padding: EdgeInsets.only(left: 5),
                child: AnimatedDigitWidget(
                  value: _accountAmountController.value,
                  textStyle: TextStyle(color: Colors.white, fontSize: 10),
                  fractionDigits: 2,
                  enableDigitSplit: true,
                  digitSplitSymbol: ",",
                ),
              )
            ],
          ),
        ),
        Padding(
          padding: EdgeInsets.only(left: 20),
          child: GestureDetector(
            onTap: () {
              Navigator.pushNamed(context, 'WithdrawnPage');
            },
            child: Image.asset(
              'images/wallet-app-bar.png',
              width: 24,
            ),
          ),
        )
      ],
    );
  }
}
